package com.han.hotelplat.comm.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.SimpleTimeZone;
import java.util.TimeZone;

import org.apache.log4j.Logger;

public class DateUtil {

	private static Logger log = Logger.getLogger(DateUtil.class);

	public static String Y_cn = "yyyy年";
	public static String YM_cn = "yyyy年MM月";
	public static String YM = "yyyy-MM";
	public static String YMD = "yyyy-MM-dd";
	public static String YMDHMS = "yyyy-MM-dd HH:mm:ss";
	public static String YMDHM = "yyyy-MM-dd HH:mm";
	public static String HM = "HH:mm";
	public static String HMS = "HH:mm:ss";
	public static String ymd = "yyyyMMdd";
	
	public final static long DAY = 24 * 60 * 60 * 1000;
	public final static long HOUR = 60 * 60 * 1000;
	public final static long MINUTE = 60 * 1000;
	public final static long SECOND = 1000;

	public static String formatY_cn(Date date) {
		return format(date, Y_cn);
	}

	public static String formatYM_cn(Date date) {
		return format(date, YM_cn);
	}

	public static String formatYM(Date date) {
		return format(date, YM);
	}

	public static String formatYMD(Date date) {
		return format(date, YMD);
	}

	public static String formatYMDHM(Date date) {
		return format(date, YMDHM);
	}

	public static String formatYMDHMS(Date date) {
		return format(date, YMDHMS);
	}
	
	public static String formatHMS(Date date) {
		return format(date, HMS);
	}

	public static String formatYMDHMS(Long dateTime) {
		return format(dateTime, YMDHMS);
	}

	public static String formatHM(Long dateTime) {
		return format(dateTime, HM);
	}

	public static String formatHMS(Long dateTime) {
		return format(dateTime, HMS);
	}

	public static String format(Date date, String pattern) {
		if (date == null) {
			return "";
		} else {
			SimpleDateFormat formater = new SimpleDateFormat();
			formater.applyPattern(pattern);
			return formater.format(date);
		}
	}

	public static String format(Long dateTime, String pattern) {
		if (dateTime == null) {
			return "";
		} else {
			SimpleDateFormat formater = new SimpleDateFormat();
			formater.applyPattern(pattern);
			return formater.format(dateTime);
		}
	}

	public static Date parseHM(String strDate) {
		return parse(strDate, HM);
	}

	public static Date parseYMD(String strDate) {
		return parse(strDate, YMD);
	}

	public static Date parseYMDHM(String strDate) {
		return parse(strDate, YMDHM);
	}

	public static Date parseYMDHMS(String strDate) {
		return parse(strDate, YMDHMS);
	}
	
	public static Date parseymd(String strDate) {
		return parse(strDate, ymd);
	}
	public static Date parse(String strDate, String pattern) {
		if (strDate == null || strDate.trim().length() == 0) {
			return null;
		} else {
			SimpleDateFormat formater = new SimpleDateFormat();
			formater.applyPattern(pattern);
			try {
				return formater.parse(strDate.toString());
			} catch (ParseException e) {
				e.printStackTrace();
				System.err.println("错误：时间转换出错:"+strDate);
				return null;
			}
		}
	}

	public static int getYear(Date date) {
		Calendar cld = Calendar.getInstance();
		cld.setTime(date);
		return cld.get(Calendar.YEAR);
	}

	public static Integer getMonth(Date date) {
		Calendar cld = Calendar.getInstance();
		cld.setTime(date);
		return cld.get(Calendar.MONTH) + 1;
	}

	public static int getDay(Date date) {
		Calendar cld = Calendar.getInstance();
		cld.setTime(date);
		return cld.get(Calendar.DAY_OF_MONTH);
	}

	public static Date addDay(Date date, int day) {
		Calendar rightNow = Calendar.getInstance();
		rightNow.setTime(date);
		rightNow.add(Calendar.DAY_OF_YEAR, day);// 日期加10天
		return rightNow.getTime();
	}

	/**
	 * 
	 * @description
	 * @author han1088
	 * @param date 要转换的时间
	 * @param timeZoneOffset 目标时间的时区东半球为+，西半球为-
	 * @return
	 */
	public static String getFormatedDateString(Date date, float timeZoneOffset) {
		if (timeZoneOffset > 13 || timeZoneOffset < -12) {
			timeZoneOffset = 0;
		}

		int newTime = (int) (timeZoneOffset * 60 * 60 * 1000);
		TimeZone timeZone;
		String[] ids = TimeZone.getAvailableIDs(newTime);
		if (ids.length == 0) {
			timeZone = TimeZone.getDefault();
		} else {
			timeZone = new SimpleTimeZone(newTime, ids[0]);
		}

		SimpleDateFormat sdf = new SimpleDateFormat(DateUtil.YMDHMS);
		sdf.setTimeZone(timeZone);
		return sdf.format(new Date());
	}

	/**
	 * date类型转换为String类型
	 * 
	 * @param data Date类型的时间
	 * @param formatType 格式为yyyy-MM-dd HH:mm:ss//yyyy年MM月dd日 HH时mm分ss秒
	 * @return
	 */
	public static String dateToString(Date date, String formatType) {
		SimpleDateFormat sdf = new SimpleDateFormat(formatType);
		// java.util.Date date=new java.util.Date();
		return sdf.format(date);
	}

	/**
	 * long类型转换为String类型
	 * 
	 * @param currentTime 要转换的long类型的时间
	 * @param formatType 要转换的string类型的时间格式
	 * @return
	 * @throws ParseException
	 */
	public static String longToString(long currentTime, String formatType) {
		SimpleDateFormat newFormat = new SimpleDateFormat(formatType);
		Date date = null;
		try {
			date = new Date(currentTime);
		} catch (Exception e) {
			log.error("", e);
			date = new Date();
			e.printStackTrace();
		}
		return newFormat.format(date);
	}

	/**
	 * long类型转换为String类型
	 * 
	 * @param currentTime 要转换的long类型的时间
	 * @param formatType 要转换的string类型的时间格式
	 * @return
	 * @throws ParseException
	 */
	public static String longToString(long currentTime, String oldFormatType, String formatType) throws ParseException {
		String strTime = StrUtil.toStr(currentTime, StrUtil.DEFAULT_DATE); // long类型转成String
		Date date = stringToDate(strTime, oldFormatType);
		return dateToString(date, formatType);
	}

	/**
	 * string类型转换为date类型
	 * 
	 * @param strTime 的时间格式必须要与formatType的时间格式相同
	 * @param formatType 要转换的string类型的时间，formatType要转换的格式yyyy-MM-dd
	 *            HH:mm:ss//yyyy年MM月dd日HH时mm分ss秒
	 * @return
	 * @throws ParseException
	 */
	public static Date stringToDate(String strTime, String formatType) {
		try {
			SimpleDateFormat formatter = new SimpleDateFormat(formatType);
			Date date = null;
			date = formatter.parse(strTime);
			return date;
		} catch (Exception e) {
			log.error("", e);
			return new Date();
		}

	}

	/**
	 * long转换为Date类型
	 * 
	 * @param currentTime 要转换的long类型的时间
	 * @param formatType 要转换的时间格式yyyy-MM-dd HH:mm:ss//yyyy年MM月dd日 HH时mm分ss秒
	 * @return
	 * @throws ParseException
	 */
	public static Date longToDate(long currentTime, String formatType) {
		try {
			Date dateOld = new Date(currentTime); // 根据long类型的毫秒数生命一个date类型的时间
			String sDateTime = dateToString(dateOld, formatType); // 把date类型的时间转换为string
			Date date = stringToDate(sDateTime, formatType); // 把String类型转换为Date类型
			return date;
		} catch (Exception e) {
			log.error("", e);
			return new Date();
		}
	}

	/**
	 * string类型转换为long类型
	 * @param strTime  要转换的String类型的时间
	 * @param formatType 时间格式的时间格式和formatType的时间格式必须相同
	 * @return
	 * @throws ParseException
	 */
	public static long stringToLong(String strTime, String formatType) {
		try {
			Date date = stringToDate(strTime, formatType); // String类型转成date类型
			if (date == null) {
				return 0;
			} else {
				long currentTime = dateToLong(date); // date类型转成long类型
				return currentTime;
			}
		} catch (Exception e) {
			log.error("", e);
			return 0;
		}

	}

	/**
	 * date类型转换为long类型
	 * @param date 要转换的date类型的时间
	 * @return
	 */
	public static long dateToLong(Date date) {
		return StrUtil.toLong(dateToString(date, "yyyyMMddHHmmss"), StrUtil.DEFAULT_ALL);
	}

	/**
	 * 获取龙long类型时间
	 * @return yyyyMMddHHmmss
	 */
	public static long dateToLong() {
		return StrUtil.toLong(dateToString(new Date(), "yyyyMMddHHmmss"), StrUtil.DEFAULT_ALL);
	}

	/**
	 * 时间戳转Long类型时间
	 * @param unix 时间戳
	 * @return 若转换失败，返回当前时间
	 */
	public static long unixToLong(long unix) {
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
		try {
			return Long.parseLong(format.format(unix));
		} catch (Exception e) {
			log.error("", e);
			return DateUtil.dateToLong();
		}
	}

	/**
	 * 分析Long类型的时间距离当前时间多久
	 * @param time Long类型的时间。yyyyMMddHHmmss
	 * @return 若转换异常，返回DateUtil.longToString(time, "yyyy-MM-dd")
	 */
	public static String getTimePosition(long time) {
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
		Date date;
		try {
			date = format.parse(time + "");
			long conversionTime = date.getTime();
			long currentTime = System.currentTimeMillis();
			long relativeTime = currentTime - conversionTime;
			if (relativeTime < 30 * 60 * 1000) {
				return "刚刚";
			} else if (relativeTime < 60 * 60 * 1000) {
				return "30分钟前";
			} else {
				return DateUtil.longToString(time, "yyyy-MM-dd");
			}
		} catch (ParseException e) {
			log.error("", e);
			return DateUtil.longToString(time, "yyyy-MM-dd");
		}
	}

	/**
	 * 
	 * @description 获取相对给出时间的前后几天时间，-为前day天，+为后day天
	 * @author han1088
	 * @param date
	 * @param day
	 * @return
	 */
	public static Date getRelativeDay(Date date, int day) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_MONTH, day);
		date = calendar.getTime();
		return date;
	}
	
	/**
	 * 
	 * @description 获取相对给出时间的前后几个月时间，-为前month月，+为后month月
	 * @author han1088
	 * @param date
	 * @param day
	 * @return
	 */
	public static Date getRelativeMonth(Date date, int month) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MONTH, month);
		date = calendar.getTime();
		return date;
	}

	/**
	 * 
	 * @description 根据年份、月份获取该月份总天数
	 * @author han1088
	 * @param year
	 * @param month
	 * @return
	 */
	public static int getTotalDaysForMonth(int year, int month) {
		Calendar a = Calendar.getInstance();
		a.set(Calendar.YEAR, year);
		a.set(Calendar.MONTH, month - 1);
		a.set(Calendar.DATE, 1);
		a.roll(Calendar.DATE, -1);
		return a.get(Calendar.DATE);
	}

	/**
	 * 
	 * @description 根据日期获取该月份总天数
	 * @author han1088
	 * @param year
	 * @param month
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static int getTotalDaysForMonth(Date date) {
		Calendar a = Calendar.getInstance();
		a.set(Calendar.YEAR, date.getYear());
		a.set(Calendar.MONTH, date.getMonth() - 1);
		a.set(Calendar.DATE, 1);
		a.roll(Calendar.DATE, -1);
		return a.get(Calendar.DATE);
	}

	/**
	 * 
	 * @description 日期之间相隔多少天
	 * @author han1088
	 * @param year
	 * @param month
	 * @return
	 */
	public static int daysDistance(Date start, Date end) {
		Date time1 = DateUtil.parseYMD(DateUtil.formatYMD(start));
		Date time2 = DateUtil.parseYMD(DateUtil.formatYMD(end));
		int days = (int) ((time2.getTime() - time1.getTime()) / DAY);
		return days;
	}
	
	public static boolean isSamDay(Date date){
		Date now = new Date();
		if(getDay(date)==getDay(now) && getMonth(date)==getMonth(now)){
			return true;
		} 
		return false;
	}

	public boolean isSamMonth(Date date){
		Date now = new Date();
		if(getMonth(date)==getMonth(now)){
			return true;
		} 
		return false;
	}
	
	 public static boolean isThisWeek(Date date){  
	        Calendar calendar = Calendar.getInstance();  
	        int currentWeek = calendar.get(Calendar.WEEK_OF_YEAR);  
	        calendar.setTime(date);  
	        int paramWeek = calendar.get(Calendar.WEEK_OF_YEAR);  
	        if(paramWeek==currentWeek){  
	           return true;  
	        }  
	        return false;  
	}  

	 /**
	  * 获取两个日期之间的日期
	  * @param start 开始日期
	  * @param end 结束日期
	  * @return 日期集合
	  */
	 public static List<Date> getBetweenDates(Date start, Date end) {
		 String endTime = DateUtil.formatYMD(end) +" 23:59:59";
		 end = DateUtil.parseYMDHMS(endTime);
	     List<Date> result = new ArrayList<Date>();
	     Calendar tempStart = Calendar.getInstance();
	     tempStart.setTime(start);
	     tempStart.add(Calendar.DAY_OF_YEAR, 0);
	     
	     Calendar tempEnd = Calendar.getInstance();
	     tempEnd.setTime(end);
	     while (tempStart.before(tempEnd)) {
	         result.add(tempStart.getTime());
	         tempStart.add(Calendar.DAY_OF_YEAR, 1);
	     }
	     return result;
	 }
	 
	public static void main(String[] ags) {
		// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		// System.out.println(sdf.format(new Date()));
		// SimpleDateFormat sdf2 = new SimpleDateFormat("HH:mm:ss");
		List<Date> all = getBetweenDates(DateUtil.parseYMD("2018-12-01"),new Date());
		for(Date d : all){
			System.out.println(DateUtil.formatYMD(d));
		}
		
	}
}
